#ifndef COMMON_HPP
#define COMMON_HPP

#include <stdlib.h>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <memory>
#include <mutex>
#include <thread>
#include <array>
#include <math.h>

typedef struct{
    float r;
    float g;
    float b;
}Rgb;

typedef struct {
    double x;
    double y;
    double z;
}Vec3d;

typedef struct {
    double r;
    double p;
    double y;
}Euler;

class PointCloud {
public:
    PointCloud();
    ~PointCloud();

    Vec3d point_min;
    Vec3d point_max;
    Vec3d point_avg;
    Vec3d point_mid;

    std::vector<Rgb> colors;
    std::vector<Vec3d> points;

    int size();
    void clear();
    void set_max(const Vec3d& point);
    void set_min(const Vec3d& point);

    void update_max(const Vec3d& point);
    void update_min(const Vec3d& point);
    void update_avg(const Vec3d& point);
};


namespace str
{
    void replace_char(std::string& line, const char old, const char rep);
}

namespace file
{
    void read_cloud(const std::string& file_path, PointCloud& cloud, const bool read_rgb = false);
}

namespace pt
{
    void update_min(Vec3d& point_min, const Vec3d& point);
    void update_max(Vec3d& point_max, const Vec3d& point);
    Vec3d get_dimen(const Vec3d& point_min, const Vec3d& point_max);
    void point2_box_arr(const Vec3d& point, const Vec3d& dimen, float box[24]);
    void point2_box(const Vec3d& point, const Vec3d& dimen, std::array<Vec3d, 8>& box);
}

/*
namespace eg
{
    Eigen::Quaterniond euler2_quat(const Euler& euler)
    {
        Eigen::AngleAxisd roll_ang(euler.r, Eigen::Vector3d::UnitX());
        Eigen::AngleAxisd pitch_ang(euler.p, Eigen::Vector3d::UnitY());
        Eigen::AngleAxisd yaw_ang(euler.y, Eigen::Vector3d::UnitZ());
        Eigen::Quaterniond quat = yaw_ang * pitch_ang * roll_ang;
        return quat;
    }

    Eigen::Matrix3d euler2_mat(const Euler& euler)
    {
        Eigen::AngleAxisd rollAngle(euler.r,Vector3d::UnitX()));
        Eigen::AngleAxisd pitchAngle(euler.p,Vector3d::UnitY()));
        Eigen::AngleAxisd yawAngle(euler.y,Vector3d::UnitZ())); 
        Eigen::Matrix3d matrix = yawAngle*pitchAngle*rollAngle;
        return matrix;
    }
}
*/

#endif